package com.moliku.insurance.process.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.moliku.insurance.common.constant.CompanyEnum;
import com.moliku.insurance.common.constant.InsureStatusEnum;
import com.moliku.insurance.common.constant.OrderEnum;
import com.moliku.insurance.common.constant.PolicyConfigKeyEnum;
import com.moliku.insurance.common.response.CommonInsureResult;
import com.moliku.insurance.model.dto.CancelInsureDTO;
import com.moliku.insurance.model.dto.DownloadInsureDTO;
import com.moliku.insurance.model.dto.insure.InsureDTO;
import com.moliku.insurance.model.dto.insure.InsuredInfoDTO;
import com.moliku.insurance.model.entity.Order;
import com.moliku.insurance.model.entity.OrderDetail;
import com.moliku.insurance.model.entity.sinosafe.cancel.SinosafeCancelEntity;
import com.moliku.insurance.model.entity.sinosafe.submit.SinosofaEntity;
import com.moliku.insurance.process.mapper.BaseOrderMapper;
import com.moliku.insurance.process.strategy.PolicyStrategy;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 华安保险
 *
 * @author Mr.Liu
 * @since 2021/2/25
 */
@Slf4j
@Service("SinoSafeService")
@AllArgsConstructor
public class SinoSafeServiceImpl implements PolicyStrategy {
    private static final String RESPONSE_CODE = "errCode";

    private final RestTemplate restTemplate;
    private final BaseOrderMapper baseOrderMapper;
    private final ConfigServiceImpl configService;
    private final String BASE_WOMAN = "0";


    @Override
    public CommonInsureResult submitPolicy(InsureDTO request) {
        //判断当前订单是否为空
        Order order = baseOrderMapper.selectById(request.getLocalOrderId());
        if (null == order) {
            log.info("华安投保失败,未查询到该订单:{}", request.getLocalOrderId());
            return CommonInsureResult.submitPolicyFail(InsureStatusEnum.INSURE_FAIL_5102);
        }
        String submitUrl = configService.getConfigValue(CompanyEnum.SINOSAFE, PolicyConfigKeyEnum.SUBMIT_POLICY_URL);
        String json = getJsonStr(request);
        //请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        //请求体
        HttpEntity<String> httpEntity = new HttpEntity<>(json, headers);
        //发起请求
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(submitUrl, httpEntity, String.class);
        JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
        log.info("华安投保返回:{}", jsonObject);

        //保存返回结果
        OrderDetail orderDetail = baseOrderMapper.selectDeatailByOrderId(order.getId());
        orderDetail.setInsureRsp(responseEntity.getBody());
        baseOrderMapper.updateOrderDeatailByOrderId(orderDetail);

        if (0 == jsonObject.getInteger(RESPONSE_CODE)) {
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray results = data.getJSONArray("results");
            JSONObject resultsJSONObject = results.getJSONObject(0);
            //电子保单地址
            order.setUrl(resultsJSONObject.getString("elecAddr"));
            order.setStatus(OrderEnum.CLOSED_NO_REFUND.getValue());
            order.setPolicyNo(resultsJSONObject.getString("policyNo"));
            baseOrderMapper.updateById(order);
            log.info("投保成功!{}", jsonObject);
            return CommonInsureResult.submitPolicySuccess(jsonObject.getString("policyNo"));
        }
        return CommonInsureResult.submitPolicyFail(jsonObject.getString("errMsg"));
    }

    @Override
    public CommonInsureResult cancelPolicy(CancelInsureDTO request) {

        Order order = baseOrderMapper.selectByPolicyNoAndCompany(request.getPolicyNo(), CompanyEnum.SINOSAFE.getCode());
        if (null == order) {
            return CommonInsureResult.cancelPolicyFail(InsureStatusEnum.CANCEL_INSURE_FAIL_5202);
        }

        SinosafeCancelEntity sinosafeCancelEntity = new SinosafeCancelEntity();
        //渠道
        SinosafeCancelEntity.Channel channel = new SinosafeCancelEntity.Channel();
        channel.setAccessUser(configService.getConfigValue(CompanyEnum.SINOSAFE, PolicyConfigKeyEnum.USERNAME));
        channel.setAccessPassword(configService.getConfigValue(CompanyEnum.SINOSAFE, PolicyConfigKeyEnum.PASSWORD));
        sinosafeCancelEntity.setChannel(channel);

        //保单信息
        SinosafeCancelEntity.Policy policy = new SinosafeCancelEntity.Policy();
        policy.setPolicyNo(request.getPolicyNo());

        policy.setProductCode(order.getProduct());
        policy.setBusinessNo(order.getSerialNo());
        sinosafeCancelEntity.setPolicy(policy);

        //转为json
        String json = JSONObject.toJSONString(sinosafeCancelEntity);
        //请求头
        HttpHeaders headers = new HttpHeaders();

        headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);

        //请求体
        HttpEntity<String> httpEntity = new HttpEntity<>(json, headers);

        //发起请求
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(configService.getConfigValue(CompanyEnum.SINOSAFE, PolicyConfigKeyEnum.SUBMIT_POLICY_URL), httpEntity, String.class);
        JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
        log.info("华安退保返回:{}", jsonObject);
        //保存返回结果
        OrderDetail orderDetail = baseOrderMapper.selectDeatailByOrderId(order.getId());
        orderDetail.setCancelPolicyRsp(JSONUtil.toJsonStr(jsonObject));
        baseOrderMapper.updateOrderDeatailByOrderId(orderDetail);

        if (0 == jsonObject.getInteger(RESPONSE_CODE)) {
            log.info("退保成功!{}", jsonObject);
            //更改订单状态
            order.setStatus(OrderEnum.CANCEL.getValue());
            baseOrderMapper.updateById(order);
            return CommonInsureResult.cancelPolicySuccess();
        }
        return CommonInsureResult.cancelPolicyFail(jsonObject.getString("errMsg"));
    }

    @Override
    public CommonInsureResult downloadPolicy(DownloadInsureDTO downloadInsure) {
        return null;
    }


    /**
     * 拼接参数
     *
     * @param request
     * @return
     */
    private String getJsonStr(InsureDTO request) {
        //渠道
        String code;
        if (ObjectUtil.isNotEmpty(request.getOrder().getChannel2Code())) {
            code = request.getOrder().getChannel2Code();
        } else {
            code = request.getOrder().getChannel1Code();
        }

        //总信息
        SinosofaEntity sinosofaEntity = new SinosofaEntity();

        //渠道信息
        SinosofaEntity.SaleInfo saleInfo = new SinosofaEntity.SaleInfo();
        saleInfo.setAccessUser(configService.getConfigValue(CompanyEnum.SINOSAFE, PolicyConfigKeyEnum.USERNAME));
        saleInfo.setAccessPassword(configService.getConfigValue(CompanyEnum.SINOSAFE, PolicyConfigKeyEnum.PASSWORD));
        saleInfo.setChannelCode(code);
        sinosofaEntity.setSaleInfo(saleInfo);

        //产品信息
        SinosofaEntity.Product product = new SinosofaEntity.Product();
        product.setProductCode(request.getOrder().getProductCode());
        //TODO 套餐代码
//        product.setPackageCode(request.getOrder().getPlanCode());
        sinosofaEntity.setProduct(product);

        //投保信息
        SinosofaEntity.Policy policy = new SinosofaEntity.Policy();
        policy.setBusinessNo(request.getOrder().getSerialNumber());
        policy.setActualPremiumAmt(Integer.parseInt(String.valueOf((request.getOrder().getPremium().multiply(new BigDecimal("100"))))));
        policy.setInsuredQuantity(1);
        policy.setOriginalPremiumAmt(Integer.parseInt(String.valueOf((request.getOrder().getPremium().multiply(new BigDecimal("100"))))));
        //TODO 总保额
//        policy.setTotalInsuredAmt(Integer.parseInt(String.valueOf(request.getOrder().getPremium())));
        policy.setInsuredBgnTime(DateUtil.format(DateUtil.parse(request.getOrder().getStartTime()), "yyyyMMddHHmmss"));
        policy.setInsuredEndTime(DateUtil.format(DateUtil.parse(request.getOrder().getEndTime()), "yyyyMMddHHmmss"));
        policy.setAppTime(DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss"));
        sinosofaEntity.setPolicy(policy);


        //投保人
        SinosofaEntity.Holder holder = new SinosofaEntity.Holder();
        holder.setHolderName(request.getPolicyHolder().getcName());
        holder.setIdcartType(SinosofaEntity.map.get(request.getPolicyHolder().getCardType()));
        holder.setIdcartNo(request.getPolicyHolder().getCardNo());
        //TODO 投保人类型
        holder.setHolderType("1");
        holder.setBornDate(DateUtil.format(DateUtil.parse(request.getPolicyHolder().getBirthDay()), "yyyyMMdd"));
        //TODO  性别
        holder.setSex(BASE_WOMAN.equals(request.getPolicyHolder().getSex()) ? "F" : "M");
        sinosofaEntity.setHolder(holder);

        //被保人
        List<SinosofaEntity.Insured> insuredList = new ArrayList<>();
        List<InsuredInfoDTO> insureds = request.getInsureds();
        for (InsuredInfoDTO insured : insureds) {
            SinosofaEntity.Insured data = new SinosofaEntity.Insured();
            data.setInsuredName(insured.getCName());
            data.setIdcartType(SinosofaEntity.map.get(insured.getCardType()));
            data.setBornDate(insured.getBirthDay());
            data.setIdcartNo(insured.getCardNo());
            //TODO
            data.setReleation("14");
            data.setSex(BASE_WOMAN.equals(insured.getSex()) ? "F" : "M");
            //被保人类型
            data.setInsuredType("01");
            insuredList.add(data);
        }
        sinosofaEntity.setInsureds(insuredList);
        return JSONObject.toJSONString(sinosofaEntity);
    }
}
